import { HTMLAttributes, useState, type FC } from 'react';
import classNames from 'classnames';
import { useUpdateEffect } from 'react-use';
import { CSSObject, jsx } from '@emotion/react';
import { modalDefaultProps } from './defaultProps';
import type { ModalOptions } from './type';
import { useModalContext } from './ModalContext';
import ModalGroup from './ModalGroup';
import ModalHeader from './ModalHeader';
import ModalContent from './ModalContent';
import ModalDescription from './ModalDescription';
import ModalActions from './ModalActions';

export interface ModalProps extends ModalOptions, HTMLAttributes<HTMLDivElement> {}

interface ModalInterface extends FC<ModalProps> {
  Group: typeof ModalGroup;
  Header: typeof ModalHeader;
  Content: typeof ModalContent;
  Description: typeof ModalDescription;
  Actions: typeof ModalActions;
}

const Modal: ModalInterface = (props) => {
  const { className, ui, active, basic, duration, fullscreen, size, inverted, children, forwardedRef, ...modalProps } =
    props;
  const [states, setStates] = useModalContext();
  const [css, setCss] = useState<string>();
  const [styles, setStyles] = useState<CSSObject>();

  useUpdateEffect(() => {
    setStates({ ...states, active });
    if (active) {
      setCss(classNames('animating', 'transition', 'scale', 'in'));
      setStyles({ display: 'block !important', animationDuration: `${duration}ms` });
      setTimeout(() => {
        setCss(classNames('transition', 'visible', 'active'));
        setStyles({ display: 'block !important' });
      }, duration);
    } else {
      setCss(classNames('animating', 'transition', 'visible', 'scale', 'out'));
      setStyles({ display: 'block !important', animationDuration: `${duration}ms` });
      setTimeout(() => {
        setCss(classNames('transition', 'hidden'));
        setStyles(undefined);
      }, duration);
    }
  }, [active]);

  return jsx(
    'div',
    {
      ref: forwardedRef,
      className: classNames({ ui, basic }, size, fullscreen, { fullscreen, inverted }, 'modal', css, className),
      css: styles,
      onClick: (e: MouseEvent) => e.stopPropagation(),
      ...modalProps,
    },
    children,
  );
};

Modal.displayName = 'Modal';
Modal.defaultProps = modalDefaultProps;

Modal.Group = ModalGroup;
Modal.Header = ModalHeader;
Modal.Content = ModalContent;
Modal.Description = ModalDescription;
Modal.Actions = ModalActions;

export default Modal;
